import { defineStore } from 'pinia'
import { store } from '../index'
import { cloneDeep } from 'lodash-es'
import { StorageEnum } from '@/designer/BigScreen/enums/storageEnum'
import { storageLocal } from '@/utils/storage'
import { LayoutType, LayerModeEnum, ChartModeEnum } from './layoutStore.d'
import { getComponent, getCanRemoveParentId, findVisibleLength, findFirstVisible, findLastVisible } from '@/designer/BigScreen/views/Workstation/utils'
import { buildUUID } from '@/utils/uuid'
import { isArray } from '@/utils/is'
import { getParent } from '@/designer/BigScreen/views/Workstation/utils'
const { CK_CHART_LAYOUT_STORE } = StorageEnum

const storageChartLayout: Partial<LayoutType> = storageLocal.getItem(CK_CHART_LAYOUT_STORE)

export const useLayoutStore = defineStore('layout', () => {
  const layout: any = ref({
    root: [],
    wrapper: [
      {
        key: 'CkToolbar',
        visible: true,
        title: '工具栏',
        icon: 'ep:check',
        id: '',
        pid: '',
        config: {
          dragType: 'toolbar',
          acceptDragType: [],
          canDrag: true,
          canDrop: false,
          position: 'wrapper'
        },
        options: {
          attr: { x: 5, y: 0, w: 0, h: 0, zIndex: 1 },
          minWidth: null,
          minHeight: null,
          maxWidth: null,
          maxHeight: null
        },
        children: []
      }
    ],
    content: [],
    left: [
      {
        key: 'CkAside',
        visible: true,
        title: '',
        icon: '',
        id: '',
        pid: '',
        config: {
          dragType: 'aside',
          acceptDragType: ['aside'],
          canDrag: true,
          canDrop: true,
          position: 'left'
        },
        options: {
          attr: { x: 0, y: 0, w: 304, h: 0, zIndex: 1 },
          minWidth: 304,
          minHeight: null,
          maxWidth: null,
          maxHeight: null
        },
        children: [
          {
            key: 'CkColumn',
            visible: true,
            title: '',
            icon: '',
            id: '',
            pid: '',
            config: {
              dragType: 'column',
              acceptDragType: [],
              canDrag: false,
              canDrop: false,
              position: 'left'
            },
            options: {
              attr: { x: 0, y: 0, w: 64, h: 0, zIndex: 1 },
              minWidth: 64,
              minHeight: null,
              maxWidth: null,
              maxHeight: null
            },
            children: [
              {
                key: 'CkPackage',
                visible: true,
                title: '组件',
                icon: 'ep:check',
                id: '',
                pid: '',
                config: {
                  dragType: 'package',
                  acceptDragType: ['aside', 'tab', 'item', 'package'],
                  canDrag: true,
                  canDrop: true,
                  position: 'left'
                },
                options: {
                  attr: { x: 0, y: 0, w: 64, h: 0, zIndex: 1 },
                  minWidth: 64,
                  minHeight: null,
                  maxWidth: null,
                  maxHeight: null
                },
                children: []
              }
            ]
          }
        ]
      }
    ],
    right: [
      {
        key: 'CkAside',
        visible: true,
        title: '',
        icon: '',
        id: '',
        pid: '',
        config: {
          dragType: 'aside',
          acceptDragType: ['aside'],
          canDrag: true,
          canDrop: true,
          position: 'right'
        },
        options: {
          attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
          minWidth: 240,
          minHeight: null,
          maxWidth: null,
          maxHeight: null
        },
        children: [
          {
            key: 'CkColumn',
            visible: true,
            title: '',
            icon: '',
            id: '',
            pid: '',
            config: {
              dragType: 'column',
              acceptDragType: [],
              canDrag: false,
              canDrop: false,
              position: 'right'
            },
            options: {
              attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
              minWidth: 240,
              minHeight: null,
              maxWidth: null,
              maxHeight: null
            },
            children: [
              {
                key: 'CkTab',
                visible: true,
                title: '',
                icon: '',
                id: '',
                pid: '',
                config: {
                  dragType: 'tab',
                  acceptDragType: ['aside', 'tab', 'item', 'package'],
                  canDrag: true,
                  canDrop: true,
                  position: 'right'
                },
                options: {
                  attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                  minWidth: 240,
                  minHeight: null,
                  maxWidth: null,
                  maxHeight: null
                },
                children: [
                  {
                    key: 'CkData',
                    visible: true,
                    title: '数据',
                    icon: 'ep:check',
                    active: true,
                    id: '',
                    pid: '',
                    config: {
                      dragType: 'item',
                      acceptDragType: ['item'],
                      canDrag: true,
                      canDrop: true,
                      position: 'right'
                    },
                    options: {
                      attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                      minWidth: 240,
                      minHeight: null,
                      maxWidth: null,
                      maxHeight: null
                    },
                    children: []
                  },
                  {
                    key: 'CkEvent',
                    visible: true,
                    title: '事件',
                    icon: 'ep:check',
                    active: false,
                    id: '',
                    pid: '',
                    config: {
                      dragType: 'item',
                      acceptDragType: ['item'],
                      canDrag: true,
                      canDrop: true,
                      position: 'right'
                    },
                    options: {
                      attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                      minWidth: 240,
                      minHeight: null,
                      maxWidth: null,
                      maxHeight: null
                    },
                    children: []
                  }
                ]
              },
              {
                key: 'CkTab',
                visible: true,
                title: '',
                icon: '',
                id: '',
                pid: '',
                config: {
                  dragType: 'tab',
                  acceptDragType: ['aside', 'tab', 'item', 'package'],
                  canDrag: true,
                  canDrop: true,
                  position: 'right'
                },
                options: {
                  attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                  minWidth: 240,
                  minHeight: null,
                  maxWidth: null,
                  maxHeight: null
                },
                children: [
                  {
                    key: 'CkCharacter',
                    visible: true,
                    title: '字符',
                    icon: 'ep:check',
                    active: true,
                    id: '',
                    pid: '',
                    config: {
                      dragType: 'item',
                      acceptDragType: ['item'],
                      canDrag: true,
                      canDrop: true,
                      position: 'right'
                    },
                    options: {
                      attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                      minWidth: 240,
                      minHeight: null,
                      maxWidth: null,
                      maxHeight: null
                    },
                    children: []
                  },
                  {
                    key: 'CkParagraph',
                    visible: true,
                    title: '段落',
                    icon: 'ep:check',
                    active: false,
                    id: '',
                    pid: '',
                    config: {
                      dragType: 'item',
                      acceptDragType: ['item'],
                      canDrag: true,
                      canDrop: true,
                      position: 'right'
                    },
                    options: {
                      attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                      minWidth: 240,
                      minHeight: null,
                      maxWidth: null,
                      maxHeight: null
                    },
                    children: []
                  },
                  {
                    key: 'CkFilter',
                    visible: true,
                    title: '滤镜',
                    icon: 'ep:check',
                    active: false,
                    id: '',
                    pid: '',
                    config: {
                      dragType: 'item',
                      acceptDragType: ['item'],
                      canDrag: true,
                      canDrop: true,
                      position: 'right'
                    },
                    options: {
                      attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                      minWidth: 240,
                      minHeight: null,
                      maxWidth: null,
                      maxHeight: null
                    },
                    children: []
                  }
                ]
              },
              {
                key: 'CkTab',
                visible: true,
                title: '',
                icon: '',
                id: '',
                pid: '',
                config: {
                  dragType: 'tab',
                  acceptDragType: ['aside', 'tab', 'item', 'package'],
                  canDrag: true,
                  canDrop: true,
                  position: 'right'
                },
                options: {
                  attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                  minWidth: 240,
                  minHeight: null,
                  maxWidth: null,
                  maxHeight: null
                },
                children: [
                  {
                    key: 'CkHistory',
                    visible: true,
                    title: '历史记录',
                    icon: 'ep:check',
                    active: true,
                    id: '',
                    pid: '',
                    config: {
                      dragType: 'item',
                      acceptDragType: ['item'],
                      canDrag: true,
                      canDrop: true,
                      position: 'right'
                    },
                    options: {
                      attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                      minWidth: 240,
                      minHeight: null,
                      maxWidth: null,
                      maxHeight: null
                    },
                    children: []
                  }
                ]
              }
            ]
          },
          {
            key: 'CkColumn',
            visible: true,
            title: '',
            icon: '',
            id: '',
            pid: '',
            config: {
              dragType: 'column',
              acceptDragType: [],
              canDrag: false,
              canDrop: false,
              position: 'right'
            },
            options: {
              attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
              minWidth: 240,
              minHeight: null,
              maxWidth: null,
              maxHeight: null
            },
            children: [
              {
                key: 'CkTab',
                visible: true,
                title: '',
                icon: '',
                id: '',
                pid: '',
                config: {
                  dragType: 'tab',
                  acceptDragType: ['aside', 'tab', 'item', 'package'],
                  canDrag: true,
                  canDrop: true,
                  position: 'right'
                },
                options: {
                  attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                  minWidth: 240,
                  minHeight: null,
                  maxWidth: null,
                  maxHeight: null
                },
                children: [
                  {
                    key: 'CkProperty',
                    visible: true,
                    title: '属性',
                    icon: 'ep:check',
                    active: true,
                    id: '',
                    pid: '',
                    config: {
                      dragType: 'item',
                      acceptDragType: ['item'],
                      canDrag: true,
                      canDrop: true,
                      position: 'right'
                    },
                    options: {
                      attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                      minWidth: 240,
                      minHeight: null,
                      maxWidth: null,
                      maxHeight: null
                    },
                    children: []
                  }
                ]
              },
              {
                key: 'CkTab',
                visible: true,
                title: '',
                icon: '',
                id: '',
                pid: '',
                config: {
                  dragType: 'tab',
                  acceptDragType: ['aside', 'tab', 'item', 'package'],
                  canDrag: true,
                  canDrop: true,
                  position: 'right'
                },
                options: {
                  attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                  minWidth: 240,
                  minHeight: null,
                  maxWidth: null,
                  maxHeight: null
                },
                children: [
                  {
                    key: 'CkLayer',
                    visible: true,
                    title: '图层',
                    icon: 'ep:check',
                    active: true,
                    id: '',
                    pid: '',
                    config: {
                      dragType: 'item',
                      acceptDragType: ['item'],
                      canDrag: true,
                      canDrop: true,
                      position: 'right'
                    },
                    options: {
                      attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
                      minWidth: 240,
                      minHeight: null,
                      maxWidth: null,
                      maxHeight: null
                    },
                    children: []
                  }
                ]
              }
            ]
          }
        ]
      }
    ],
    bottom: [
      {
        key: 'CkTab',
        visible: false,
        title: '',
        icon: '',
        id: '',
        pid: '',
        config: {
          dragType: 'tab',
          acceptDragType: ['tab', 'item'],
          canDrag: true,
          canDrop: true,
          position: 'bottom'
        },
        options: {
          attr: { x: 0, y: 0, w: 240, h: 160, zIndex: 1 },
          minWidth: 240,
          minHeight: null,
          maxWidth: null,
          maxHeight: null
        },
        children: [
          {
            key: 'CkAnimation',
            visible: false,
            title: '动画',
            icon: 'ep:check',
            active: true,
            id: '',
            pid: '',
            config: {
              dragType: 'item',
              acceptDragType: ['item'],
              canDrag: true,
              canDrop: true,
              position: 'bottom'
            },
            options: {
              attr: { x: 0, y: 0, w: 240, h: 0, zIndex: 1 },
              minWidth: 240,
              minHeight: null,
              maxWidth: null,
              maxHeight: null
            },
            children: []
          }
        ]
      }
    ]
  })

  const layoutVisible = ref({
    CkCharacter: { visible: true, position: 'right', parent: [] },
    CkParagraph: { visible: true, position: 'right', parent: [] },
    CkFilter: { visible: true, position: 'right', parent: [] },
    CkLayer: { visible: true, position: 'right', parent: [] },
    CkProperty: { visible: true, position: 'right', parent: [] },
    CkHistory: { visible: true, position: 'right', parent: [] },
    CkData: { visible: true, position: 'right', parent: [] },
    CkAnimation: { visible: false, position: 'bottom', parent: [] },
    CkEvent: { visible: true, position: 'right', parent: [] },
    CkPackage: { visible: true, position: 'left', parent: [] },
    CkToolbar: { visible: true, position: 'wrapper', parent: [] }
  })
  // 是否正在被拖拽
  const isLayoutDragging = ref(false)
  // 是否靠近了可放置区域
  const isNear = ref(false)
  // 是否靠近了自己
  const isNearSelf = ref(false)
  // 将要被放置在哪个区域
  const dropTo = ref('')
  // 放置的层级
  const dropLevel = ref('')
  // 将要被放置的位置索引， -1即放置在最后
  const dropIndex = ref(-1)
  // 将要被放置的父级标识，为空即为根级，与dropTo配合确定放置在哪儿
  const dropId = ref('')
  // 当前正在被拖拽的预览视图
  const currentDragging = ref(null)
  // 当前正在被拖拽的页节点
  const currentDragModule = ref(null)
  // 是否是item排序
  const isItemSort = ref(false)
  const state: LayoutType = reactive({
    // 图层控制
    layers: true,
    // 图表组件
    charts: true,
    // 详情设置（收缩为true）
    details: false,
    // 组件列表展示类型（默认单列）
    chartType: ChartModeEnum.SINGLE,
    // 图层类型（默认图片）
    layerType: LayerModeEnum.THUMBNAIL,
    // 当前加载数量
    percentage: 0,
    // 是否重置当前画布位置
    rePositionCanvas: false,
    // 防止值不存在
    ...storageChartLayout
  })

  // 初始化注册组件数据
  const initLayout = () => {
    for (const key in layout.value) {
      layout.value[key] = initComponentInstall(layout.value[key])
      recursionGetParent(layout.value[key])
    }
    console.log(layoutVisible.value, 'parent')
  }

  // 注册组件信息
  const initComponentInstall = (data) => {
    const res = cloneDeep(data)
    recursionComponentInstall(res, '')
    return res
  }

  // 递归注册组件信息
  const recursionComponentInstall = (data, pid) => {
    data.forEach((item) => {
      item.pid = pid
      item.component = shallowRef(getComponent(item.key).default)
      if (!item.id) {
        item.id = buildUUID()
      }
      if (item.children && item.children.length > 0) {
        recursionComponentInstall(item.children, item.id)
      }
    })
  }

  const recursionGetParent = (data) => {
    data.forEach((item) => {
      if (item.config.dragType === 'item' || item.config.dragType === 'package' || item.config.dragType === 'toolbar') {
        layoutVisible.value[item.key].parent = getParent(layout.value[item.config.position], item.id)
      }
      if (item.children && item.children.length > 0) {
        recursionGetParent(item.children)
      }
    })
  }

  const recursionGetPosition = (data) => {
    data.forEach((item) => {
      if (item.config.dragType === 'item' || item.config.dragType === 'package' || item.config.dragType === 'toolbar') {
        layoutVisible.value[item.key].position = item.config.position
      }
      if (item.children && item.children.length > 0) {
        recursionGetPosition(item.children)
      }
    })
  }

  const updateVisible = (data, position) => {
    if (position === 'bottom') {
      data.forEach((item) => {
        item.visible = findVisible(item.children)
      })
    } else {
      if (position === 'root') {
        data.forEach((item) => {
          if (item.key !== 'CkToolbar') {
            item.children.forEach((v) => {
              v.children.forEach((k) => {
                if (k.key === 'CkPackage') {
                  v.visible = k.visible
                  item.visible = findVisible(item.children)
                } else {
                  k.visible = findVisible(k.children)
                  v.visible = findVisible(v.children)
                  item.visible = findVisible(item.children)
                }
              })
            })
          }
        })
      } else {
        data.forEach((item) => {
          item.children.forEach((v) => {
            v.children.forEach((k) => {
              if (k.key === 'CkPackage') {
                v.visible = k.visible
                item.visible = findVisible(item.children)
              } else {
                k.visible = findVisible(k.children)
                v.visible = findVisible(v.children)
                item.visible = findVisible(item.children)
              }
            })
          })
        })
      }
    }
  }

  // 设置组件的显示隐藏
  const installComponent = (type) => {
    layoutVisible.value[type].visible = !layoutVisible.value[type].visible
    if (type !== 'CkToolbar') {
      recursionSetItemVisible(layout.value[layoutVisible.value[type].position], type)
      if (layoutVisible.value[type].visible) {
        if (type === 'CkPackage') {
          const asideIndex = layout.value[layoutVisible.value[type].position].findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 1])
          const columnIndex = layout.value[layoutVisible.value[type].position][asideIndex].children.findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 2])
          layout.value[layoutVisible.value[type].position][asideIndex].visible = true
          layout.value[layoutVisible.value[type].position][asideIndex].children[columnIndex].visible = true
        } else {
          if (layoutVisible.value[type].position === 'bottom') {
            const tabIndex = layout.value[layoutVisible.value[type].position].findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 1])
            layout.value[layoutVisible.value[type].position][tabIndex].visible = true
          } else {
            const asideIndex = layout.value[layoutVisible.value[type].position].findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 1])
            const columnIndex = layout.value[layoutVisible.value[type].position][asideIndex].children.findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 2])
            const tabIndex = layout.value[layoutVisible.value[type].position][asideIndex].children[columnIndex].children.findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 3])
            layout.value[layoutVisible.value[type].position][asideIndex].visible = true
            layout.value[layoutVisible.value[type].position][asideIndex].children[columnIndex].visible = true
            layout.value[layoutVisible.value[type].position][asideIndex].children[columnIndex].children[tabIndex].visible = true
          }
        }
      } else {
        if (type === 'CkPackage') {
          const asideIndex = layout.value[layoutVisible.value[type].position].findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 1])
          const columnIndex = layout.value[layoutVisible.value[type].position][asideIndex].children.findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 2])
          layout.value[layoutVisible.value[type].position][asideIndex].children[columnIndex].visible = false
          layout.value[layoutVisible.value[type].position][asideIndex].visible = findVisible(layout.value[layoutVisible.value[type].position][asideIndex].children)
        } else {
          if (layoutVisible.value[type].position === 'bottom') {
            const tabIndex = layout.value[layoutVisible.value[type].position].findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 1])
            layout.value[layoutVisible.value[type].position][tabIndex].visible = findVisible(layout.value[layoutVisible.value[type].position][tabIndex].children)
          } else {
            const asideIndex = layout.value[layoutVisible.value[type].position].findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 1])
            const columnIndex = layout.value[layoutVisible.value[type].position][asideIndex].children.findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 2])
            const tabIndex = layout.value[layoutVisible.value[type].position][asideIndex].children[columnIndex].children.findIndex((v) => v.id === layoutVisible.value[type].parent[layoutVisible.value[type].parent.length - 3])
            layout.value[layoutVisible.value[type].position][asideIndex].children[columnIndex].children[tabIndex].visible = findVisible(layout.value[layoutVisible.value[type].position][asideIndex].children[columnIndex].children[tabIndex].children)
            layout.value[layoutVisible.value[type].position][asideIndex].children[columnIndex].visible = findVisible(layout.value[layoutVisible.value[type].position][asideIndex].children[columnIndex].children)
            layout.value[layoutVisible.value[type].position][asideIndex].visible = findVisible(layout.value[layoutVisible.value[type].position][asideIndex].children)
          }
        }
      }
    } else {
      layout.value[layoutVisible.value[type].position].forEach((item) => {
        if (item.key === type) {
          item.visible = layoutVisible.value[type].visible
        }
      })
    }
  }

  const findVisible = (data) => {
    let isVisible = false
    for (let i = 0; i < data.length; i++) {
      if (data[i].visible) {
        isVisible = true
        break
      }
    }
    return isVisible
  }

  const recursionSetItemVisible = (data, key) => {
    data.forEach((item) => {
      if (item.id === layoutVisible.value[key].parent[1]) {
        const index = item.children.findIndex((v) => v.id === layoutVisible.value[key].parent[0])
        if (layoutVisible.value[key].visible) {
          item.children[index].visible = true
          item.children.forEach((v, idx) => {
            v.active = false
            if (idx === index) {
              v.active = true
            }
          })
        } else {
          item.children[index].visible = false
          if (item.children[index].active) {
            if (index === 0) {
              const idx = item.children.findIndex((v, i) => i > index && v.visible)
              if (idx > 0) {
                item.children[idx].active = true
              }
            } else {
              const res = []
              item.children.forEach((v, idx) => {
                if (idx < index && v.visible) {
                  res.push(idx)
                }
              })
              if (res.length > 0) {
                item.children[res[res.length - 1]].active = true
              }
            }
          }
        }
      }
      if (item.children && item.children.length > 0) {
        recursionSetItemVisible(item.children, key)
      }
    })
  }

  const moveLayout = (item) => {
    const res = updateLayout(item)
    switch (dropTo.value) {
      case 'content':
        layout.value.content.push(res)
        break
      case 'wrapper':
        layout.value.wrapper.push(res)
        break
      case 'left':
        insertLayout(layout.value.left, res)
        break
      case 'right':
        insertLayout(layout.value.right, res)
        break
      case 'bottom':
        insertLayout(layout.value.bottom, res)
        break
      default:
        insertLayout(layout.value.root, res)
        resetRootLayoutZIndex()
        break
    }
    recursionGetParent(layout.value[dropTo.value])
    recursionGetPosition(layout.value[dropTo.value])
    if (!isItemSort.value) {
      if (currentDragging.value.key !== 'CkToolbar') {
        updateVisible(layout.value[dropTo.value], dropTo.value)
        updateVisible(layout.value[currentDragging.value.config.position], currentDragging.value.config.position)
      }
      isLayoutDragging.value = false
      currentDragModule.value = null
      currentDragging.value = null
      dropLevel.value = ''
    } else {
      currentDragModule.value.index = dropIndex.value
      currentDragging.value.index = dropIndex.value
    }
    isNear.value = false
    isNearSelf.value = false
    dropTo.value = ''
    dropIndex.value = -1
    dropId.value = ''
  }

  // 将拖拽的组件插入新的位置
  const insertLayout = (data, res) => {
    if (isArray(res)) {
      recursionInsertLayout(data, res, res[0].pid)
    } else {
      recursionInsertLayout(data, res, res.pid)
    }
  }

  const recursionInsertLayout = (data, res, pid) => {
    if (pid === '') {
      if (dropIndex.value === -1) {
        if (isArray(res)) {
          data.push(...res)
        } else {
          data.push(res)
        }
      } else {
        if (isArray(res)) {
          data.splice(dropIndex.value, 0, ...res)
        } else {
          data.splice(dropIndex.value, 0, res)
        }
      }
    } else {
      data.forEach((item) => {
        if (item.id === pid) {
          if (item.config.dragType === 'tab' && dropLevel.value === 'item' && !isItemSort.value) {
            item.children.forEach((v) => {
              v.active = false
            })
          }
          if (dropIndex.value === -1) {
            if (isArray(res)) {
              item.children.push(...res)
            } else {
              item.children.push(res)
            }
          } else {
            if (isArray(res)) {
              item.children.splice(dropIndex.value, 0, ...res)
            } else {
              item.children.splice(dropIndex.value, 0, res)
            }
          }
        } else {
          if (item.children && item.children.length > 0) {
            recursionInsertLayout(item.children, res, pid)
          }
        }
      })
    }
  }

  // 重置索引值
  const resetRootLayoutZIndex = () => {
    layout.value.root.forEach((item, index) => {
      item.options.attr.zIndex = 100 + index
    })
  }

  // 更新拖拽组件数据
  const updateLayout = (res) => {
    res.isNearMain = undefined
    res.index = undefined
    let result = null
    let asideIndex = -1
    let columnIndex = -1
    let tabIndex = -1
    let columnVisibleLength = 0
    let tabVisibleLength = 0
    let itemVisibleLength = 0
    let currentModule = null
    switch (res.config.dragType) {
      case 'toolbar':
        currentModule = cloneDeep(res)
        removeLayout(layout.value[res.config.position], res)
        currentModule.parent = undefined
        result = setCurrentDraggingModule(currentModule)
        break
      case 'package':
        if (res.config.position === 'root') {
          asideIndex = layout.value[res.config.position].findIndex((v) => v.id === res.parent[res.parent.length - 1])
          columnVisibleLength = findVisibleLength(layout.value[res.config.position][asideIndex].children)
          if (columnVisibleLength > 1) {
            currentModule = cloneDeep(res)
            removeLayout(layout.value[res.config.position], res)
            currentModule.parent = undefined
            if (dropLevel.value === 'aside') {
              result = getAsideModule(dropTo.value, currentModule.options.attr)
              result.children.push(getColumnModule(dropTo.value, currentModule.options.attr))
              result.children[0].children.push(setCurrentDraggingModule(currentModule))
            } else {
              result = getColumnModule(dropTo.value, currentModule.options.attr)
              result.children.push(setCurrentDraggingModule(currentModule))
            }
          } else {
            currentModule = cloneDeep(layout.value[res.config.position][asideIndex])
            currentModule.parent = [res.parent[res.parent.length - 1]]
            currentModule.options.attr.x = res.options.attr.x
            currentModule.options.attr.y = res.options.attr.y
            removeLayout(layout.value[res.config.position], currentModule)
            currentModule.parent = undefined
            if (dropLevel.value === 'aside') {
              result = setCurrentDraggingModule(currentModule)
            } else {
              result = setCurrentDraggingModule(currentModule).children
            }
          }
        } else {
          currentModule = cloneDeep(res)
          removeLayout(layout.value[res.config.position], res)
          currentModule.parent = undefined
          if (dropLevel.value === 'aside') {
            result = getAsideModule(dropTo.value, currentModule.options.attr)
            result.children.push(getColumnModule(dropTo.value, currentModule.options.attr))
            result.children[0].children.push(setCurrentDraggingModule(currentModule))
          } else {
            result = getColumnModule(dropTo.value, currentModule.options.attr)
            result.children.push(setCurrentDraggingModule(currentModule))
          }
        }
        break
      case 'tab':
        if (res.config.position === 'root') {
          asideIndex = layout.value[res.config.position].findIndex((v) => v.id === res.parent[res.parent.length - 1])
          columnIndex = layout.value[res.config.position][asideIndex].children.findIndex((v) => v.id === res.parent[res.parent.length - 2])
          columnVisibleLength = findVisibleLength(layout.value[res.config.position][asideIndex].children)
          tabVisibleLength = findVisibleLength(layout.value[res.config.position][asideIndex].children[columnIndex].children)
          if (columnVisibleLength === 1) {
            if (tabVisibleLength === 1) {
              if (dropLevel.value === 'aside') {
                currentModule = cloneDeep(layout.value[res.config.position][asideIndex])
                currentModule.parent = [res.parent[res.parent.length - 1]]
                currentModule.options.attr.x = res.options.attr.x
                currentModule.options.attr.y = res.options.attr.y
                removeLayout(layout.value[res.config.position], currentModule)
                currentModule.parent = undefined
                result = setCurrentDraggingModule(currentModule)
              } else if (dropLevel.value === 'column') {
                currentModule = cloneDeep(layout.value[res.config.position][asideIndex])
                currentModule.parent = [res.parent[res.parent.length - 1]]
                currentModule.options.attr.x = res.options.attr.x
                currentModule.options.attr.y = res.options.attr.y
                removeLayout(layout.value[res.config.position], currentModule)
                currentModule.parent = undefined
                result = setCurrentDraggingModule(currentModule).children
              } else if (dropLevel.value === 'tab') {
                currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex])
                currentModule.parent = [res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                currentModule.options.attr.x = res.options.attr.x
                currentModule.options.attr.y = res.options.attr.y
                removeLayout(layout.value[res.config.position], currentModule)
                currentModule.parent = undefined
                result = setCurrentDraggingModule(currentModule).children
              } else {
                currentModule = cloneDeep(res)
                removeLayout(layout.value[res.config.position], currentModule)
                result = setCurrentDraggingModule(currentModule).children
              }
            } else {
              currentModule = cloneDeep(res)
              removeLayout(layout.value[res.config.position], res)
              currentModule.parent = undefined
              if (dropLevel.value === 'aside') {
                result = getAsideModule(dropTo.value, currentModule.options.attr)
                result.children.push(getColumnModule(dropTo.value, currentModule.options.attr))
                result.children[0].children.push(setCurrentDraggingModule(currentModule))
              } else if (dropLevel.value === 'column') {
                result = getColumnModule(dropTo.value, currentModule.options.attr)
                result.children.push(setCurrentDraggingModule(currentModule))
              } else if (dropLevel.value === 'tab') {
                result = setCurrentDraggingModule(currentModule)
              } else {
                result = setCurrentDraggingModule(currentModule).children
              }
            }
          } else {
            if (tabVisibleLength === 1) {
              if (dropLevel.value === 'aside') {
                currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex])
                currentModule.parent = [res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                currentModule.options.attr.x = res.options.attr.x
                currentModule.options.attr.y = res.options.attr.y
                removeLayout(layout.value[res.config.position], currentModule)
                currentModule.parent = undefined
                result = getAsideModule(dropTo.value, currentModule.options.attr)
                result.children.push(setCurrentDraggingModule(currentModule))
              } else if (dropLevel.value === 'column') {
                currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex])
                currentModule.parent = [res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                currentModule.options.attr.x = res.options.attr.x
                currentModule.options.attr.y = res.options.attr.y
                removeLayout(layout.value[res.config.position], currentModule)
                currentModule.parent = undefined
                result = setCurrentDraggingModule(currentModule)
              } else if (dropLevel.value === 'tab') {
                currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex])
                currentModule.parent = [res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                currentModule.options.attr.x = res.options.attr.x
                currentModule.options.attr.y = res.options.attr.y
                removeLayout(layout.value[res.config.position], currentModule)
                currentModule.parent = undefined
                result = setCurrentDraggingModule(currentModule).children
              } else {
                currentModule = cloneDeep(res)
                removeLayout(layout.value[res.config.position], currentModule)
                result = setCurrentDraggingModule(currentModule).children
              }
            } else {
              currentModule = cloneDeep(res)
              removeLayout(layout.value[res.config.position], res)
              currentModule.parent = undefined
              if (dropLevel.value === 'aside') {
                result = getAsideModule(dropTo.value, currentModule.options.attr)
                result.children.push(getColumnModule(dropTo.value, currentModule.options.attr))
                result.children[0].children.push(setCurrentDraggingModule(currentModule))
              } else if (dropLevel.value === 'column') {
                result = getColumnModule(dropTo.value, currentModule.options.attr)
                result.children.push(setCurrentDraggingModule(currentModule))
              } else if (dropLevel.value === 'tab') {
                result = setCurrentDraggingModule(currentModule)
              } else {
                result = setCurrentDraggingModule(currentModule).children
              }
            }
          }
        } else {
          currentModule = cloneDeep(res)
          removeLayout(layout.value[res.config.position], res)
          currentModule.parent = undefined
          if (dropLevel.value === 'aside') {
            result = getAsideModule(dropTo.value, currentModule.options.attr)
            result.children.push(getColumnModule(dropTo.value, currentModule.options.attr))
            result.children[0].children.push(setCurrentDraggingModule(currentModule))
          } else if (dropLevel.value === 'column') {
            result = getColumnModule(dropTo.value, currentModule.options.attr)
            result.children.push(setCurrentDraggingModule(currentModule))
          } else if (dropLevel.value === 'tab') {
            result = setCurrentDraggingModule(currentModule)
          } else {
            result = setCurrentDraggingModule(currentModule).children
          }
        }
        break
      case 'aside':
        if (dropLevel.value === 'aside') {
          currentModule = cloneDeep(res)
          removeLayout(layout.value[res.config.position], res)
          currentModule.parent = undefined
          result = setCurrentDraggingModule(currentModule)
        } else if (dropLevel.value === 'column') {
          currentModule = cloneDeep(res)
          removeLayout(layout.value[res.config.position], res)
          currentModule.parent = undefined
          result = setCurrentDraggingModule(currentModule).children
        } else if (dropLevel.value === 'tab') {
          columnIndex = findFirstVisible(res.children)
          currentModule = cloneDeep(res.children[columnIndex])
          currentModule.parent = [res.children[columnIndex].id, res.id]
          currentModule.options.attr.x = res.options.attr.x
          currentModule.options.attr.y = res.options.attr.y
          removeLayout(layout.value[res.config.position], currentModule)
          currentModule.parent = undefined
          result = setCurrentDraggingModule(currentModule).children
        } else {
          columnIndex = findFirstVisible(res.children)
          tabIndex = findFirstVisible(res.children[columnIndex].children)
          currentModule = cloneDeep(res.children[columnIndex].children[tabIndex])
          currentModule.parent = [res.children[columnIndex].children[tabIndex].id, res.children[columnIndex].id, res.id]
          currentModule.options.attr.x = res.options.attr.x
          currentModule.options.attr.y = res.options.attr.y
          removeLayout(layout.value[res.config.position], currentModule)
          currentModule.parent = undefined
          result = setCurrentDraggingModule(currentModule).children
        }
        break
      default:
        if (isItemSort.value) {
          res.index = dropIndex.value
          result = setCurrentDraggingModule(res)
        } else {
          if (res.config.position === 'root') {
            asideIndex = layout.value[res.config.position].findIndex((v) => v.id === res.parent[res.parent.length - 1])
            columnIndex = layout.value[res.config.position][asideIndex].children.findIndex((v) => v.id === res.parent[res.parent.length - 2])
            tabIndex = layout.value[res.config.position][asideIndex].children[columnIndex].children.findIndex((v) => v.id === res.parent[res.parent.length - 3])
            columnVisibleLength = findVisibleLength(layout.value[res.config.position][asideIndex].children)
            tabVisibleLength = findVisibleLength(layout.value[res.config.position][asideIndex].children[columnIndex].children)
            itemVisibleLength = findVisibleLength(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex].children)
            if (columnVisibleLength === 1) {
              if (tabVisibleLength === 1) {
                if (itemVisibleLength === 1) {
                  if (dropLevel.value === 'aside') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex])
                    currentModule.parent = [res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule)
                  } else if (dropLevel.value === 'column') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex])
                    currentModule.parent = [res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule).children
                  } else if (dropLevel.value === 'tab') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex])
                    currentModule.parent = [res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule).children
                  } else {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                    currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule).children
                  }
                } else {
                  currentModule = cloneDeep(res)
                  removeLayout(layout.value[res.config.position], res)
                  currentModule.parent = undefined
                  if (res.active && layout.value[res.config.position].length > 0) {
                    updateDefaultTabActive(layout.value[res.config.position], res.pid)
                  }
                  if (dropLevel.value === 'aside') {
                    result = getAsideModule(dropTo.value, res.options.attr)
                    result.children.push(getColumnModule(dropTo.value, res.options.attr))
                    result.children[0].children.push(getTabModule(dropTo.value, res.options.attr))
                    result.children[0].children[0].children.push(setCurrentDraggingModule(res))
                    result.children[0].children[0].children[0].active = true
                  } else if (dropLevel.value === 'column') {
                    result = getColumnModule(dropTo.value, res.options.attr)
                    result.children.push(getTabModule(dropTo.value, res.options.attr))
                    result.children[0].children.push(setCurrentDraggingModule(res))
                    result.children[0].children[0].active = true
                  } else if (dropLevel.value === 'tab') {
                    result = getTabModule(dropTo.value, res.options.attr)
                    result.children.push(setCurrentDraggingModule(res))
                    result.children[0].active = true
                  } else {
                    result = setCurrentDraggingModule(res)
                    result.active = true
                  }
                }
              } else {
                if (itemVisibleLength === 1) {
                  if (dropLevel.value === 'aside') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                    currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = getAsideModule(dropTo.value, currentModule.options.attr)
                    result.children.push(getColumnModule(dropTo.value, currentModule.options.attr))
                    result.children[0].children.push(setCurrentDraggingModule(currentModule))
                  } else if (dropLevel.value === 'column') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                    currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = getColumnModule(dropTo.value, res.options.attr)
                    result.children.push(setCurrentDraggingModule(currentModule))
                  } else if (dropLevel.value === 'tab') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                    currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule)
                  } else {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                    currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule).children
                  }
                } else {
                  currentModule = cloneDeep(res)
                  removeLayout(layout.value[res.config.position], res)
                  currentModule.parent = undefined
                  if (res.active && layout.value[res.config.position].length > 0) {
                    updateDefaultTabActive(layout.value[res.config.position], res.pid)
                  }
                  if (dropLevel.value === 'aside') {
                    result = getAsideModule(dropTo.value, res.options.attr)
                    result.children.push(getColumnModule(dropTo.value, res.options.attr))
                    result.children[0].children.push(getTabModule(dropTo.value, res.options.attr))
                    result.children[0].children[0].children.push(setCurrentDraggingModule(res))
                    result.children[0].children[0].children[0].active = true
                  } else if (dropLevel.value === 'column') {
                    result = getColumnModule(dropTo.value, res.options.attr)
                    result.children.push(getTabModule(dropTo.value, res.options.attr))
                    result.children[0].children.push(setCurrentDraggingModule(res))
                    result.children[0].children[0].active = true
                  } else if (dropLevel.value === 'tab') {
                    result = getTabModule(dropTo.value, res.options.attr)
                    result.children.push(setCurrentDraggingModule(res))
                    result.children[0].active = true
                  } else {
                    result = setCurrentDraggingModule(res)
                    result.active = true
                  }
                }
              }
            } else {
              if (tabVisibleLength === 1) {
                if (itemVisibleLength === 1) {
                  if (dropLevel.value === 'aside') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex])
                    currentModule.parent = [res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = getAsideModule(dropTo.value, currentModule.options.attr)
                    result.children.push(setCurrentDraggingModule(currentModule))
                  } else if (dropLevel.value === 'column') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex])
                    currentModule.parent = [res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule)
                  } else if (dropLevel.value === 'tab') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex])
                    currentModule.parent = [res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule).children
                  } else {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                    currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule).children
                  }
                } else {
                  currentModule = cloneDeep(res)
                  removeLayout(layout.value[res.config.position], res)
                  currentModule.parent = undefined
                  if (res.active && layout.value[res.config.position].length > 0) {
                    updateDefaultTabActive(layout.value[res.config.position], res.pid)
                  }
                  if (dropLevel.value === 'aside') {
                    result = getAsideModule(dropTo.value, res.options.attr)
                    result.children.push(getColumnModule(dropTo.value, res.options.attr))
                    result.children[0].children.push(getTabModule(dropTo.value, res.options.attr))
                    result.children[0].children[0].children.push(setCurrentDraggingModule(res))
                    result.children[0].children[0].children[0].active = true
                  } else if (dropLevel.value === 'column') {
                    result = getColumnModule(dropTo.value, res.options.attr)
                    result.children.push(getTabModule(dropTo.value, res.options.attr))
                    result.children[0].children.push(setCurrentDraggingModule(res))
                    result.children[0].children[0].active = true
                  } else if (dropLevel.value === 'tab') {
                    result = getTabModule(dropTo.value, res.options.attr)
                    result.children.push(setCurrentDraggingModule(res))
                    result.children[0].active = true
                  } else {
                    result = setCurrentDraggingModule(res)
                    result.active = true
                  }
                }
              } else {
                if (itemVisibleLength === 1) {
                  if (dropLevel.value === 'aside') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                    currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = getAsideModule(dropTo.value, currentModule.options.attr)
                    result.children.push(getColumnModule(dropTo.value, currentModule.options.attr))
                    result.children[0].children.push(setCurrentDraggingModule(currentModule))
                  } else if (dropLevel.value === 'column') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                    currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = getColumnModule(dropTo.value, res.options.attr)
                    result.children.push(setCurrentDraggingModule(currentModule))
                  } else if (dropLevel.value === 'tab') {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                    currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule)
                  } else {
                    currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                    currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                    currentModule.options.attr.x = res.options.attr.x
                    currentModule.options.attr.y = res.options.attr.y
                    removeLayout(layout.value[res.config.position], currentModule)
                    currentModule.parent = undefined
                    result = setCurrentDraggingModule(currentModule).children
                  }
                } else {
                  currentModule = cloneDeep(res)
                  removeLayout(layout.value[res.config.position], res)
                  currentModule.parent = undefined
                  if (res.active && layout.value[res.config.position].length > 0) {
                    updateDefaultTabActive(layout.value[res.config.position], res.pid)
                  }
                  if (dropLevel.value === 'aside') {
                    result = getAsideModule(dropTo.value, res.options.attr)
                    result.children.push(getColumnModule(dropTo.value, res.options.attr))
                    result.children[0].children.push(getTabModule(dropTo.value, res.options.attr))
                    result.children[0].children[0].children.push(setCurrentDraggingModule(res))
                    result.children[0].children[0].children[0].active = true
                  } else if (dropLevel.value === 'column') {
                    result = getColumnModule(dropTo.value, res.options.attr)
                    result.children.push(getTabModule(dropTo.value, res.options.attr))
                    result.children[0].children.push(setCurrentDraggingModule(res))
                    result.children[0].children[0].active = true
                  } else if (dropLevel.value === 'tab') {
                    result = getTabModule(dropTo.value, res.options.attr)
                    result.children.push(setCurrentDraggingModule(res))
                    result.children[0].active = true
                  } else {
                    result = setCurrentDraggingModule(res)
                    result.active = true
                  }
                }
              }
            }
          } else {
            if (res.config.position === 'bottom') {
              tabIndex = layout.value[res.config.position].findIndex((v) => v.id === res.parent[res.parent.length - 1])
              itemVisibleLength = findVisibleLength(layout.value[res.config.position][tabIndex].children)
              if (itemVisibleLength === 1) {
                if (dropLevel.value === 'aside') {
                  currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                  currentModule.parent = [res.parent[res.parent.length - 1]]
                  currentModule.options.attr.x = res.options.attr.x
                  currentModule.options.attr.y = res.options.attr.y
                  removeLayout(layout.value[res.config.position], currentModule)
                  currentModule.parent = undefined
                  result = getAsideModule(dropTo.value, res.options.attr)
                  result.children.push(getColumnModule(dropTo.value, res.options.attr))
                  result.children[0].children.push(setCurrentDraggingModule(currentModule))
                } else if (dropLevel.value === 'column') {
                  currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                  currentModule.parent = [res.parent[res.parent.length - 1]]
                  currentModule.options.attr.x = res.options.attr.x
                  currentModule.options.attr.y = res.options.attr.y
                  removeLayout(layout.value[res.config.position], currentModule)
                  currentModule.parent = undefined
                  result = getColumnModule(dropTo.value, res.options.attr)
                  result.children.push(setCurrentDraggingModule(currentModule))
                } else if (dropLevel.value === 'tab') {
                  currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                  currentModule.parent = [res.parent[res.parent.length - 1]]
                  currentModule.options.attr.x = res.options.attr.x
                  currentModule.options.attr.y = res.options.attr.y
                  removeLayout(layout.value[res.config.position], currentModule)
                  currentModule.parent = undefined
                  result = setCurrentDraggingModule(currentModule)
                } else {
                  currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                  currentModule.parent = [res.parent[res.parent.length - 1]]
                  currentModule.options.attr.x = res.options.attr.x
                  currentModule.options.attr.y = res.options.attr.y
                  removeLayout(layout.value[res.config.position], currentModule)
                  currentModule.parent = undefined
                  result = setCurrentDraggingModule(currentModule).children
                }
              } else {
                currentModule = cloneDeep(res)
                removeLayout(layout.value[res.config.position], res)
                currentModule.parent = undefined
                if (res.active && layout.value[res.config.position].length > 0) {
                  updateDefaultTabActive(layout.value[res.config.position], res.pid)
                }
                if (dropLevel.value === 'aside') {
                  result = getAsideModule(dropTo.value, res.options.attr)
                  result.children.push(getColumnModule(dropTo.value, res.options.attr))
                  result.children[0].children.push(getTabModule(dropTo.value, res.options.attr))
                  result.children[0].children[0].children.push(setCurrentDraggingModule(res))
                  result.children[0].children[0].children[0].active = true
                } else if (dropLevel.value === 'column') {
                  result = getColumnModule(dropTo.value, res.options.attr)
                  result.children.push(getTabModule(dropTo.value, res.options.attr))
                  result.children[0].children.push(setCurrentDraggingModule(res))
                  result.children[0].children[0].active = true
                } else if (dropLevel.value === 'tab') {
                  result = getTabModule(dropTo.value, res.options.attr)
                  result.children.push(setCurrentDraggingModule(res))
                  result.children[0].active = true
                } else {
                  result = setCurrentDraggingModule(res)
                  result.active = true
                }
              }
            } else {
              asideIndex = layout.value[res.config.position].findIndex((v) => v.id === res.parent[res.parent.length - 1])
              columnIndex = layout.value[res.config.position][asideIndex].children.findIndex((v) => v.id === res.parent[res.parent.length - 2])
              tabIndex = layout.value[res.config.position][asideIndex].children[columnIndex].children.findIndex((v) => v.id === res.parent[res.parent.length - 3])
              itemVisibleLength = findVisibleLength(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex].children)
              if (itemVisibleLength === 1) {
                if (dropLevel.value === 'aside') {
                  currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                  currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                  currentModule.options.attr.x = res.options.attr.x
                  currentModule.options.attr.y = res.options.attr.y
                  removeLayout(layout.value[res.config.position], currentModule)
                  currentModule.parent = undefined
                  result = getAsideModule(dropTo.value, res.options.attr)
                  result.children.push(getColumnModule(dropTo.value, res.options.attr))
                  result.children[0].children.push(setCurrentDraggingModule(currentModule))
                } else if (dropLevel.value === 'column') {
                  currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                  currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                  currentModule.options.attr.x = res.options.attr.x
                  currentModule.options.attr.y = res.options.attr.y
                  removeLayout(layout.value[res.config.position], currentModule)
                  currentModule.parent = undefined
                  result = getColumnModule(dropTo.value, res.options.attr)
                  result.children.push(setCurrentDraggingModule(currentModule))
                } else if (dropLevel.value === 'tab') {
                  currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                  currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                  currentModule.options.attr.x = res.options.attr.x
                  currentModule.options.attr.y = res.options.attr.y
                  removeLayout(layout.value[res.config.position], currentModule)
                  currentModule.parent = undefined
                  result = setCurrentDraggingModule(currentModule)
                } else {
                  currentModule = cloneDeep(layout.value[res.config.position][asideIndex].children[columnIndex].children[tabIndex])
                  currentModule.parent = [res.parent[res.parent.length - 3], res.parent[res.parent.length - 2], res.parent[res.parent.length - 1]]
                  currentModule.options.attr.x = res.options.attr.x
                  currentModule.options.attr.y = res.options.attr.y
                  removeLayout(layout.value[res.config.position], currentModule)
                  currentModule.parent = undefined
                  result = setCurrentDraggingModule(currentModule).children
                }
              } else {
                currentModule = cloneDeep(res)
                removeLayout(layout.value[res.config.position], res)
                currentModule.parent = undefined
                if (res.active && layout.value[res.config.position].length > 0) {
                  updateDefaultTabActive(layout.value[res.config.position], res.pid)
                }
                if (dropLevel.value === 'aside') {
                  result = getAsideModule(dropTo.value, res.options.attr)
                  result.children.push(getColumnModule(dropTo.value, res.options.attr))
                  result.children[0].children.push(getTabModule(dropTo.value, res.options.attr))
                  result.children[0].children[0].children.push(setCurrentDraggingModule(res))
                  result.children[0].children[0].children[0].active = true
                } else if (dropLevel.value === 'column') {
                  result = getColumnModule(dropTo.value, res.options.attr)
                  result.children.push(getTabModule(dropTo.value, res.options.attr))
                  result.children[0].children.push(setCurrentDraggingModule(res))
                  result.children[0].children[0].active = true
                } else if (dropLevel.value === 'tab') {
                  result = getTabModule(dropTo.value, res.options.attr)
                  result.children.push(setCurrentDraggingModule(res))
                  result.children[0].active = true
                } else {
                  result = setCurrentDraggingModule(res)
                  result.active = true
                }
              }
            }
          }
        }
        break
    }
    updateLayoutId(result, dropId.value)
    return result
  }

  // 更新拖拽组件id继承关系
  const updateLayoutId = (res, pid) => {
    if (isArray(res)) {
      recursionUpdateLayoutId(res, pid)
    } else {
      res.pid = pid
      if (!res.id) {
        res.id = buildUUID()
      }
      if (res.children && res.children.length > 0) {
        recursionUpdateLayoutId(res.children, res.id)
      }
    }
  }

  // 递归更新拖拽组件id继承关系
  const recursionUpdateLayoutId = (data, pid) => {
    data.forEach((item) => {
      item.pid = pid
      if (!item.id) {
        item.id = buildUUID()
      }
      if (item.children && item.children.length > 0) {
        recursionUpdateLayoutId(item.children, item.id)
      }
    })
  }

  // 更新默认的tab项选中状态
  const updateDefaultTabActive = (data, pid) => {
    data.forEach((item) => {
      if (item.id === pid) {
        const itemIndex = findLastVisible(item.children)
        item.children[itemIndex].active = true
      } else {
        if (item.children && item.children.length > 0) {
          updateDefaultTabActive(item.children, pid)
        }
      }
    })
  }

  // 获取侧边拖拽组件原始数据
  const getAsideModule = (position, attr) => {
    return {
      key: 'CkAside',
      id: buildUUID(),
      pid: '',
      visible: true,
      title: '',
      icon: '',
      component: shallowRef(getComponent('CkAside').default),
      config: {
        dragType: 'aside',
        acceptDragType: ['aside'],
        canDrag: true,
        canDrop: true,
        position
      },
      options: {
        attr,
        minWidth: 240,
        minHeight: null,
        maxWidth: null,
        maxHeight: null
      },
      children: []
    }
  }

  // 获取列拖拽组件原始数据
  const getColumnModule = (position, attr) => {
    return {
      key: 'CkColumn',
      id: buildUUID(),
      pid: '',
      visible: true,
      title: '',
      icon: '',
      component: shallowRef(getComponent('CkColumn').default),
      config: {
        dragType: 'column',
        acceptDragType: [],
        canDrag: false,
        canDrop: false,
        position
      },
      options: {
        attr,
        minWidth: 240,
        minHeight: null,
        maxWidth: null,
        maxHeight: null
      },
      children: []
    }
  }

  // 获取tab拖拽组件原始数据
  const getTabModule = (position, attr) => {
    return {
      key: 'CkTab',
      id: buildUUID(),
      pid: '',
      visible: true,
      title: '',
      icon: '',
      component: shallowRef(getComponent('CkTab').default),
      config: {
        dragType: 'tab',
        acceptDragType: position === 'bottom' ? ['tab', 'item'] : ['aside', 'tab', 'item', 'package'],
        canDrag: true,
        canDrop: true,
        position
      },
      options: {
        attr,
        minWidth: 240,
        minHeight: null,
        maxWidth: null,
        maxHeight: null
      },
      children: []
    }
  }

  // 设置当前正在拖拽的组件注册
  const setCurrentDraggingModule = (res) => {
    const result = cloneDeep(res)
    result.component = markRaw(getComponent(result.key).default)
    result.config.position = dropTo.value
    if (result.config.dragType === 'tab') {
      result.config.acceptDragType = dropTo.value === 'bottom' ? ['tab', 'item'] : ['aside', 'tab', 'item', 'package']
    }
    if (result.children && result.children.length > 0) {
      recursionCurrentSonModuleInstall(result.children)
    }
    return result
  }

  // 递归设置当前正在拖拽的组件注册
  const recursionCurrentSonModuleInstall = (data) => {
    data.forEach((item) => {
      item.component = markRaw(getComponent(item.key).default)
      item.config.position = dropTo.value
      if (item.config.dragType === 'tab') {
        item.config.acceptDragType = dropTo.value === 'bottom' ? ['tab', 'item'] : ['aside', 'tab', 'item', 'package']
      }
      if (item.children && item.children.length > 0) {
        recursionCurrentSonModuleInstall(item.children)
      }
    })
  }

  // 设置当前正在拖拽的预览组件注册
  const setCurrentDraggingPreviewModule = (res) => {
    currentDragModule.value = cloneDeep(res)
    const item = cloneDeep(res)
    item.component = markRaw(getComponent(item.key).default)
    if (item.children && item.children.length > 0) {
      recursionCurrentSonPreviewModuleInstall(item.children)
    }
    let result = null
    if (item.config.position === 'root') {
      if (item.config.dragType === 'package' || item.config.dragType === 'tab') {
        const dragAsideIndex = layout.value.root.findIndex((v) => v.id === item.parent[item.parent.length - 1])
        const dragColumnIndex = layout.value.root[dragAsideIndex].children.findIndex((v) => v.id === item.parent[item.parent.length - 2])
        if (findVisibleLength(layout.value.root[dragAsideIndex].children) === 1 && findVisibleLength(layout.value.root[dragAsideIndex].children[dragColumnIndex].children) === 1) {
          result = getAsideModule(item.config.position, item.options.attr)
          result.children.push(getColumnModule(item.config.position, item.options.attr))
          result.children[0].children.push(item)
        } else {
          result = item
        }
      } else {
        if (item.config.dragType === 'item') {
          if (isItemSort.value) {
            result = item
            result.component = shallowRef(getComponent('CkItem').default)
          } else {
            const dragAsideIndex = layout.value.root.findIndex((v) => v.id === item.parent[item.parent.length - 1])
            const dragColumnIndex = layout.value.root[dragAsideIndex].children.findIndex((v) => v.id === item.parent[item.parent.length - 2])
            const dragTabIndex = layout.value.root[dragAsideIndex].children[dragColumnIndex].children.findIndex((v) => v.id === item.parent[item.parent.length - 3])
            if (
              findVisibleLength(layout.value.root[dragAsideIndex].children) === 1 &&
              findVisibleLength(layout.value.root[dragAsideIndex].children[dragColumnIndex].children) === 1 &&
              findVisibleLength(layout.value.root[dragAsideIndex].children[dragColumnIndex].children[dragTabIndex].children) === 1
            ) {
              result = getAsideModule(item.config.position, item.options.attr)
              result.children.push(getColumnModule(item.config.position, item.options.attr))
              result.children[0].children.push(getTabModule(item.config.position, item.options.attr))
              result.children[0].children[0].children.push(item)
            } else {
              result = getTabModule(item.config.position, item.options.attr)
              result.children.push(item)
            }
          }
        } else {
          result = item
        }
      }
    } else {
      if (item.config.dragType === 'item') {
        if (isItemSort.value) {
          result = item
          result.component = shallowRef(getComponent('CkItem').default)
        } else {
          result = getTabModule(item.config.position, item.options.attr)
          result.children.push(item)
        }
      } else {
        result = item
      }
    }
    currentDragging.value = result
  }

  // 递归设置当前正在拖拽的预览组件注册
  const recursionCurrentSonPreviewModuleInstall = (data) => {
    data.forEach((item) => {
      item.component = markRaw(getComponent(item.key).default)
      if (item.children && item.children.length > 0) {
        recursionCurrentSonPreviewModuleInstall(item.children)
      }
    })
  }

  // 递归删除原位置上的拖拽组件数据
  const removeLayout = (data, res) => {
    if (res.parent) {
      if (res.parent.length > 1) {
        const result = getCanRemoveParentId(data, res.id)
        if (result.pid === '') {
          if (result.count > 1) {
            data[result.index].children.splice(result.childIndex, 1)
          } else {
            data.splice(result.index, 1)
          }
        } else {
          recursionRemoveLayout(data, result)
        }
      } else {
        data.splice(res.index, 1)
      }
    }
  }

  // 递归删除数据
  const recursionRemoveLayout = (data, res) => {
    data.forEach((item) => {
      if (item.id === res.id) {
        item.children.splice(res.childIndex, 1)
      } else {
        if (item.children && item.children.length > 0) {
          recursionRemoveLayout(item.children, res)
        }
      }
    })
  }

  // 选项卡切换事件
  const changeTab = (res) => {
    findTabPosition(layout.value[res.config.position], res)
  }

  // 递归寻找tab项进行选中切换
  const findTabPosition = (data, res) => {
    data.forEach((item) => {
      if (item.id === res.pid) {
        item.children.forEach((v) => {
          v.active = false
          if (v.id === res.id) {
            v.active = true
          }
        })
      } else {
        if (item.children && item.children.length > 0) {
          findTabPosition(item.children, res)
        }
      }
    })
  }

  return {
    layout,
    dropTo,
    dropLevel,
    dropIndex,
    dropId,
    layoutVisible,
    isLayoutDragging,
    isNear,
    isNearSelf,
    currentDragging,
    currentDragModule,
    isItemSort,
    ...toRefs(state),
    initLayout,
    installComponent,
    moveLayout,
    setCurrentDraggingPreviewModule,
    changeTab
  }
})

export const useLayoutStoreWithOut = () => {
  return useLayoutStore(store)
}
